﻿using System;
using System.IO;
// 无论是否抛出异常，也不管try程序块是否完全执行，finally程序块总是被执行。通常用finally程序块来清除代码。

// 在以下情况下执行finally程序块：
//    catch块执行完成
//    由于跳转语句（如return或goto）离开try块
//    try块结束

namespace _104_try语句和异常_finally程序块
{
    class Program
    {
        //finally块为程序添加了决定性内容，在下面实例中，无论是否符合以下条件，打开的文件总能被关闭：
        //    try块正常结束
        //    因为是空文件，提前返回EndOfStream
        //    读取文件时抛出IOException异常
        static void ReadFile()
        {
            StreamReader reader = null; // System.IO命名空间
            try
            {
                reader = File.OpenText("file.text");
                if (reader.EndOfStream) return;
                Console.WriteLine(reader.ReadToEnd());
            }
            finally
            {
                if (reader != null) reader.Dispose();
            }
        }
        //本例通过在StreamReader上调用Dispose方法来关闭文件。在finally块中调用对象的Dispose方法是贯穿.NET框架的标准约定，且在C#的using语句中也明确支持。

        // using语句
        // 许多类内部封装了非托管资源，例如文件管理、图像管理、数据库连接等。这些类实现System.IDisposable接口，这个接口定义了一个名为Dispose的无参数方法，用于清除这些非托管资源。
        // using语句提供了一种在finally块中调用IDisposable接口对象的Dispose方法的优雅方法。


        static void Main(string[] args)
        {
            //下面语句：
            
            using (StreamReader reader1 = File.OpenText("file.txt"))
            {
                //...
            }
            
            //完全等同于：
            
            StreamReader reader = File.OpenText("file.txt");
            try
            {
                //...
            }
            finally
            {
                if (reader != null)
                    ((IDisposable)reader).Dispose();
            }
            
        }
    }
}